<?php


/**
 *  Antz First ever DB class!
 *  Provides handy functions for common tasks to MYSQL databases
 */ 

class Antz_Db_MySQL extends Antz_Db
{
    protected $conn;
    protected $res;
    protected $showErrors;
    protected $debug;
    protected $dbType = 'MySQL';
    
    public function __construct($host, $username, $pass, $dbName, $showErrors=false)
    {
    
        if(false === ($this->conn = mysql_connect($host, $username, $pass, true))){
            // error connecting
            return false;
        };
        $this->dbName = $dbName;
        $this->showErrors($showErrors);
        return $this->switchDb($dbName);
        
    }
    
    /**
     *  Turn errors on or off
     */         
    public function showErrors($bool)
    {
        $this->showErrors = ($bool===true || $bool===false) ? $bool : false;
    }
    
    public function debug($bool)
    {
        $this->debug = ($bool === true || $bool === false) ? $bool : false;
    }
    
    /**
     *  Select another DB
     */         
    public function switchDb($dbName)
    {
        if(false===(mysql_select_db($dbName, $this->conn))){
            if($this->showErrors){
                echo 'error selecting database: '.$dbName.'<br />';
            };
            return false;
        };
        return true;
    }
    
    public static function stripSlashes($mixed)
    {
        if(is_array($mixed)){
            foreach($mixed as $k=>$v){
                $mixed[$k] = Antz_Db::stripSlashes($v);
            };
        }else{
            $mixed = stripslashes($mixed);
        };
        return $mixed;
    }
    
    /**
     *  Returns an escaped version. Make sure you escape everything you get from a user
     */         
    public function makeSafe($text)
    {
        if(is_array($text)){
            foreach($text as $k=>&$v){
                $v = $this->makeSafe($v);
            };
        }else{
            return mysql_real_escape_string($text, $this->conn);
        };
    }
    
    public function escape($text){
        return $this->makeSafe($text);
    }
    
    /**
     *  Strips any unacceptable characters, leaving only character that are safe for keys
     */
    public function makeSafeKey($text)
    {
        return preg_replace('/[^0-9a-zA-Z\-_]/', '', $text);
    }         
    
    
    /**
     *  Number of rows that are in a result set
     */         
    public function numRows()
    {
        return @mysql_num_rows($this->res);
    }
    
    /**
     *  Number of rows that were affected by the last query
     */         
    public function affectedRows()
    {
        return @mysql_affected_rows($this->conn);
    }
    
    public function fetchRow($q='')
    {
        if($q != '') if(false===$this->query($q)) return false;
        return $this->_fetchRow();
    }
    
    public function select()
    {
        return Antz::newObject('Antz_Db_Select');
    }
    
    public function delete($tablename, $where)
   { // BEGIN function delete
   	    $this->query('DELETE FROM '.$tablename. ' WHERE '.$where);
   } // END function delete
    
    public function query($q)
    {
        if(is_object($q) && $q instanceof Antz_Db_Select) $q = $q->__toString();
        if(false === ($this->res = mysql_query($q, $this->conn))){
            if($this->showErrors) echo mysql_error($this->conn).'<br />'.$q;
            return false;
        };
        if($this->debug) echo $q;
        return true;
    }
    
    protected function _fetchRow()
    {
        return mysql_fetch_assoc($this->res);
    }
    
    public function fetchAll($q)
    {
        if(false===$this->query($q))return false;
        $arr = array();
        while($r = $this->_fetchRow()){
            $arr[] = $r;
        };
        return $arr;
    }
    
    /**
     *  Inserts a new row in the db, returns insertId or false
     */         
    public function insert($table, $pairs)
    {
        $keys = array();
        $values = array();
        foreach($pairs as $k=>$v){
            $keys[] = $k;
            //echo $v.'<br />';
            $values[] = mysql_real_escape_string($v, $this->conn);
        };
        $keys = implode(', ', $keys);
        $values = implode("','", $values);
        $q = "INSERT INTO {$table} ({$keys}) VALUES ('".$values."')";
        if($this->debug) echo 'Query: '.$q.'<br />';
        if(false === ($this->res = mysql_query($q, $this->conn)) && $this->showErrors){
            echo mysql_error($this->conn).'<br />'.$q;
            return false;
        };
        return mysql_insert_id($this->conn);
    }
    
    
    public function update($tableName, $pairs, $where)
    {
        $qs = array();
        foreach($pairs as $k=>$v){
            $qs[] = $k." = '".mysql_real_escape_string($v, $this->conn)."'";
        };
        $q = "UPDATE {$tableName} SET ".implode(',', $qs)." WHERE {$where}";
        //echo $q.'<br />';
        $this->query($q);

    }
    
    

    /**
     *  Count how many rows match a condition. Useful for checking if a result exists
     *  EG:
     *     if($DB->countRows('users', array("id = '$userId'")) > 0){
     *         // we know there is a user with the corresponding id
     *     }     
     */
             
    public function countRows($tableName, $params)
    {
        return (int) $this->oneValue($tableName, 'COUNT(*)', $params);
    }

    /**
     *  Allows you to get 1 value from the db in 1 step:
     *   EG:
     *     $title = $DB->oneValue('tableName', 'title', array("id = '$topicId'"));
     */
    public function oneValue($tableName, $field, $params)
    {
        $q = "SELECT {$field} FROM {$tableName} ";
     
        if(is_array($params)) $params = implode(' AND ', $params);
        if($params != ''){
            $q .= ' WHERE '.$params;
        };
//echo $q;exit;
        $res = $this->fetchRow($q);
        if($res === false) return false;
        return $res[$field];
    }               
    
    /**
     *  Allows one field to be incremented 
     */         
    public function incrementField($table, $field, $where, $amount=1)
    {
        $where = implode(' AND ', $where);
        $q = "UPDATE {$table} SET {$field} = ({$field} + {$amount}) WHERE {$where}";
        $this->query($q);
    }
    
}
